/**
 * @author mmbro
 * @homepage https://gitee.com/mmbro/
 * @date 2021年05月19日03:37:57
 * @description 注释: 全局bean管理器
 * @link https://stackoverflow.com/questions/37711603/javascript-es6-class-definition-not-accessible-in-window-global
 */
class BeanService {
    /**
     * @description 类名,序列化时记录类型
     * @type {string}
     */
    cn = 'BeanService';

    /**
     * 静态单例服务
     * @type {*}
     * @private
     */
    static #_beanService = (() => globalThis.beanService = new BeanService())();

    /**
     * @description bean缓存对象,全局唯一
     * @type {Map<any, any>}
     */
    beanMap = new Map();

    constructor() {
        if (globalThis.beanService !== undefined) {
            console.error("invalid constructor!")
            return;
        }
        this.#init();
    }

    /**
     * @description 初始化执行内容,使用私有属性方式声明私有方法(兼容nodejs12)
     * @returns {void}
     */
    #init = () => {
        console.log(this.cn, 'init now')
    }

    /**
     * @description 获取一个bean,如果没有,则创尝试创建,失败返回null
     * @param serviceName
     * @returns {null|*}
     */
    getBean(serviceName) {
        if (typeof serviceName !== 'string' || serviceName.length === 0) {
            return null;
        }
        let bean = this.beanMap.get(serviceName);

        if (!bean) {
            bean = this.#createBean(serviceName);
        }
        return bean;
    }

    /**
     * @description 创建唯一bean,使用私有属性方式声明私有方法(兼容nodejs12)
     * @param serviceName
     * @returns {null}
     */
    #createBean = (serviceName) => {
        let camelServiceName = serviceName[0].toUpperCase() + serviceName.substr(1);
        let beanClass = globalThis[camelServiceName];
        let bean = null;
        if (typeof beanClass === 'function') {
            bean = new beanClass();
            this.beanMap.set(serviceName, bean);
        }
        return bean;
    }

    /**
     * 获取单例
     * @returns {*}
     */
    static get getInstance() {
        return this.#_beanService;
    }
}